package mark.tom.hawk;

import android.content.Context;

import java.util.HashMap;
import java.util.Map;

import androidx.annotation.NonNull;
import mark.tom.hawk.template.Converter;
import mark.tom.hawk.template.Encryption;
import mark.tom.hawk.template.Logger;
import mark.tom.hawk.template.Parser;
import mark.tom.hawk.template.Serializer;
import mark.tom.hawk.template.Storage;

import static mark.tom.hawk.C.DEFAULT_SHARED_PREFERENCES_NAME;
import static mark.tom.hawk.C.DEFAULT_SP_TAG;

public class HawkBuilder {

    private final Context context;
    private final Map<String, Storage> storageMap = new HashMap<String, Storage>();
    private Converter converter;
    private Parser parser;
    private Encryption encryption;
    private Serializer serializer;
    private Logger logger;
    private String sharedPreferencesName;

    HawkBuilder(@NonNull Context context) {
        Util.checkNull("Context", context);
        this.context = context.getApplicationContext();
    }

    public HawkBuilder addStorage(@NonNull Storage storage) {
        Util.checkNull("Storage", storage);
        this.storageMap.put(storage.tag(), storage);
        return this;
    }

    public HawkBuilder setParser(@NonNull Parser parser) {
        Util.checkNull("Parser", parser);
        this.parser = parser;
        return this;
    }

    public HawkBuilder setSerializer(@NonNull Serializer serializer) {
        Util.checkNull("Serializer", serializer);
        this.serializer = serializer;
        return this;
    }

    public HawkBuilder setLogger(@NonNull Logger logger) {
        Util.checkNull("Logger", logger);
        this.logger = logger;
        return this;
    }

    public HawkBuilder setConverter(@NonNull Converter converter) {
        Util.checkNull("Converter", converter);
        this.converter = converter;
        return this;
    }

    public HawkBuilder setEncryption(@NonNull Encryption encryption) {
        Util.checkNull("Encryption", encryption);
        this.encryption = encryption;
        return this;
    }

    public HawkBuilder setSharedPreferencesName(@NonNull String name) {
        Util.checkNull("SharedPreferencesName", name);
        this.sharedPreferencesName = name;
        return this;
    }

    public HawkBuilder closeLog() {
        getLogger().onOff(false);
        return this;
    }

    Logger getLogger() {
        if (null == logger) {
            logger = new AndroidLogger();
        }
        return logger;
    }

    Map<String, Storage> getStorage() {
        if (!storageMap.containsKey(DEFAULT_SP_TAG)) {
            // Add SharedPreferencesStorage
            Storage spStorage = new SharedPreferencesStorage(context, null == sharedPreferencesName ? DEFAULT_SHARED_PREFERENCES_NAME : sharedPreferencesName);
            storageMap.put(spStorage.tag(), spStorage);
        }
        return storageMap;
    }

    Converter getConverter() {
        if (null == converter ) {
            converter = new HawkConverter(getParser());
        }
        return converter;
    }

    private Parser getParser() {
        Util.checkNull("Hawk don‘t have a Parser. So you can define a new Parser Here", parser);
        return parser;
    }

    Encryption getEncryption() {
        if (null == encryption) {
            encryption = new Base64Encryption();
        }
        return encryption;
    }

    Serializer getSerializer() {
        if (null == serializer) {
            serializer = new HawkSerializer(getLogger());
        }
        return serializer;
    }

    public void build() {
        Hawk.build(this);
    }
}
